Tutorial step 5: changing the output frame size

How about changing the filter to produce a double-width output? Stupid, yes. Easy, yes. It only involves a minor change to the processing function and an additiona paramProc function. So let's jump in!

The paramProc function

There are too many possibilities for output sizes filters might produce given an input frame size. If this were DirectX, we'd provide a huge filterdef structure and a million caps bits to try and hold everything, but since VirtualDub's not DirectX (thank god), we have a function do it instead, paramProc:

long paramProc(FilterActivation *fa, const FilterFunctions *ff);

paramProc's job is simple: set up fa->dst to reflect the output frame format, given the input format in fa->src, and return flags indicating the behavior of the filter. The current set of flags are:

paramProc is responsible for setting the w, h, pitch, and offset fields of fa->dst. By default, fa->dst is initialized with the same width, height, and pitch as the source bitmap, and an offset of 0. Most paramProcs will set w and h, and adjust pitch to 4*w rounded up to the next 8. (8 is good for MMX.)

The offset field allows the destination window to 'float' ahead of the beginning of the buffer, and is most useful in filters that do not specify FILTERPARAM_SWAP_BUFFERS, because it allows the destination window to float anywhere in the source rectangle. Be careful, because fa->src.offset will not be zero if the (x1,y1) clipping point to the filter is not (0,0), and this will need to be added to the fa->dst.offset value.


paramProc is called as part of VirtualDub's buffer size negotiation process, before buffers are allocated. The data fields of the VBuffer structs are not valid when paramProc is called. Filters that compile tables or code dependent upon the buffer addresses should do so in startProc.

Modifying the tutorial filter for double width

First, update the FilterDefinition structure:

    tutorialParamProc,      // paramProc

Second, write paramProc. The height field is already set, so just change the width and pitch, leave the offset at zero, and inform VirtualDub that we'll be needing that separate output buffer.

long tutorialParamProc(FilterActivation *fa, const FilterFunctions *ff) {

	fa->dst.w *= 2;
	fa->dst.pitch = (fa->dst.w*4 + 7) & -8;

    return FILTERPARAM_SWAP_BUFFERS;
}

The pitch can also be set to simply fa->dst.w*4, but rounding it up to the next 8 speeds up any subsequent MMX routines using 64-bit reads.

Finally, tweak the runProc routine, by duplicating this line:

            *dst++ = new_pixel;

That's it. The filter now produces double width images. It doesn't apply filter transforms to smooth the enlargement, but that's... um... an exercise for the reader!

[up] back to main page
[prev] tutorial[4]: stop and start routines
[next] tutorial[6]: supporting user configuration


VirtualDub external filter SDK 1.05©1999-2001 Avery Lee <phaeron@virtualdub.org>